`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: CBICR, Tsinghua Univ.
// Engineer: Hongyi Li
// 
// Create Date: 2024/12/23 11:58:54
// Design Name: 
// Module Name: Switch Traversal
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module SwTrav
#(
    parameter DataWidth = 'd32,
    parameter VCNumber  = 'd4
)(
    input                   clk, rst_n,
    input           [24:0]  i_alloc_mat,
    input  [DataWidth-1:0]  i_data_e, i_data_w, i_data_n, i_data_s, i_data_l,
    output [DataWidth-1:0]  o_data_e, o_data_w, o_data_n, o_data_s, o_data_l
);

reg   [DataWidth-1:0]   reg_data_e,  reg_data_w,  reg_data_n,  reg_data_s,  reg_data_l;
wire  [DataWidth-1:0]  wire_data_e, wire_data_w, wire_data_n, wire_data_s, wire_data_l;

assign o_data_e = reg_data_e;
assign o_data_w = reg_data_w;
assign o_data_n = reg_data_n;
assign o_data_s = reg_data_s;
assign o_data_l = reg_data_l;

always @(posedge clk) begin
    if (~rst_n) begin
        reg_data_e <= 0;
        reg_data_w <= 0;
        reg_data_n <= 0;
        reg_data_s <= 0;
        reg_data_l <= 0;
    end else begin
        reg_data_e <=   i_alloc_mat[0] ? i_data_e :
                        i_alloc_mat[5] ? i_data_w :
                        i_alloc_mat[10] ? i_data_n :
                        i_alloc_mat[15] ? i_data_s :
                        i_alloc_mat[20] ? i_data_l :
                        0;
        reg_data_w <=   i_alloc_mat[1] ? i_data_e :
                        i_alloc_mat[6] ? i_data_w :
                        i_alloc_mat[11] ? i_data_n :
                        i_alloc_mat[16] ? i_data_s :
                        i_alloc_mat[21] ? i_data_l :
                        0;
        reg_data_n <=   i_alloc_mat[2] ? i_data_e :
                        i_alloc_mat[7] ? i_data_w :
                        i_alloc_mat[12] ? i_data_n :
                        i_alloc_mat[17] ? i_data_s :
                        i_alloc_mat[22] ? i_data_l :
                        0;
        reg_data_s <=   i_alloc_mat[3] ? i_data_e :
                        i_alloc_mat[8] ? i_data_w :
                        i_alloc_mat[13] ? i_data_n :
                        i_alloc_mat[18] ? i_data_s :
                        i_alloc_mat[23] ? i_data_l :
                        0;
        reg_data_l <=   i_alloc_mat[4] ? i_data_e :
                        i_alloc_mat[9] ? i_data_w :
                        i_alloc_mat[14] ? i_data_n :
                        i_alloc_mat[19] ? i_data_s :
                        i_alloc_mat[24] ? i_data_l :
                        0;
    end
end

endmodule

module SmartSwTrav
#(
    parameter DataWidth = 'd32,
    parameter VCNumber  = 'd4
)(
    input                   clk, rst_n,
    input           [24:0]  i_alloc_mat,
    input  [DataWidth-1:0]  i_data_e, i_data_w, i_data_n, i_data_s, i_data_l,
    output [DataWidth-1:0]  o_data_e, o_data_w, o_data_n, o_data_s, o_data_l
);

reg   [DataWidth-1:0]  reg_data_e, reg_data_w, reg_data_n, reg_data_s, reg_data_l;

assign o_data_e = reg_data_e;
assign o_data_w = reg_data_w;
assign o_data_n = reg_data_n;
assign o_data_s = reg_data_s;
assign o_data_l = reg_data_l;

always @(posedge clk) begin
    if (~rst_n) begin
        reg_data_e <= 0;
        reg_data_w <= 0;
        reg_data_n <= 0;
        reg_data_s <= 0;
        reg_data_l <= 0;
    end else begin
        reg_data_e <=   i_alloc_mat[0] ? i_data_e :
                        i_alloc_mat[1] ? i_data_w :
                        i_alloc_mat[2] ? i_data_n :
                        i_alloc_mat[3] ? i_data_s :
                        i_alloc_mat[4] ? i_data_l :
                        0;
        reg_data_w <=   i_alloc_mat[5] ? i_data_e :
                        i_alloc_mat[6] ? i_data_w :
                        i_alloc_mat[7] ? i_data_n :
                        i_alloc_mat[8] ? i_data_s :
                        i_alloc_mat[9] ? i_data_l :
                        0;
        reg_data_n <=   i_alloc_mat[10] ? i_data_e :
                        i_alloc_mat[11] ? i_data_w :
                        i_alloc_mat[12] ? i_data_n :
                        i_alloc_mat[13] ? i_data_s :
                        i_alloc_mat[14] ? i_data_l :
                        0;
        reg_data_s <=   i_alloc_mat[15] ? i_data_e :
                        i_alloc_mat[16] ? i_data_w :
                        i_alloc_mat[17] ? i_data_n :
                        i_alloc_mat[18] ? i_data_s :
                        i_alloc_mat[19] ? i_data_l :
                        0;
        reg_data_l <=   i_alloc_mat[20] ? i_data_e :
                        i_alloc_mat[21] ? i_data_w :
                        i_alloc_mat[22] ? i_data_n :
                        i_alloc_mat[23] ? i_data_s :
                        i_alloc_mat[24] ? i_data_l :
                        0;
    end
end

endmodule